"""
    ArrayDict is a dictionary implementation using an underlying array.

    This data structure provides a dictionary-like interface for key-value pairs, using an underlying array for storage.
    ArrayDict allows efficient key-value lookup and insertion, and supports common dictionary operations.
"""
class Array:
    """
    A simple array class that wraps around a dictionary.

    This array class supports insertion, deletion, and random access operations.
    The data in the array can be of any type.

    Attributes:
        capacity (int): The maximum capacity of the array.
    """

    def __init__(self, capacity: int = 10):
        """
        Initialize the array.

        Args:
            capacity (int, optional): The maximum capacity of the array. Defaults to 10.
        """
        self._data = {}
        self._capacity = capacity

    def __len__(self) -> int:
        """Return the number of elements in the array."""
        return len(self._data)

    def __iter__(self):
        """Yield each item in the array."""
        for item in self._data.values():
            yield item

    def __repr__(self):
        """Return a string representation of the array."""
        return f'Array(capacity={self._capacity}, data={self._data})'

    def __str__(self):
        """Return a formatted string representation of the array."""
        return '[' + ', '.join(str(item) for item in self._data.values()) + ']'

    def __getitem__(self, index: int) -> object:
        """
        Get the item at a specific index in the array.

        Args:
            index (int): The index of the item.

        Raises:
            IndexError: If the index is out of range.

        Returns:
            object: The item at the specific index.
        """
        if index < 0 or index >= len(self):
            raise IndexError('Array index out of range')
        return self._data[index]

    def __setitem__(self, index: int, value: object):
        """
        Set the value of the item at a specific index in the array.

        Args:
            index (int): The index of the item.
            value (object): The new value.

        Raises:
            IndexError: If the index is out of range.
        """
        if index < 0 or index >= len(self):
            raise IndexError('Array index out of range')
        self._data[index] = value

    def __delitem__(self, index: int):
        """
        Delete the item at a specific index in the array.

        Args:
            index (int): The index of the item.

        Raises:
            IndexError: If the index is out of range.
        """
        if index < 0 or index >= len(self):
            raise IndexError('Array index out of range')
        del self._data[index]

    def insert(self, index: int, value: int) -> bool:
        """
        Insert a value at a specific index in the array.

        Args:
            index (int): The index where the value should be inserted.
            value (int): The value to insert.

        Returns:
            bool: True if the insertion was successful, False otherwise.
        """
        if index < 0 or index > len(self) or len(self) >= self._capacity:
            return False
        else:
            self._data[index] = value
            return True


if __name__ == "__main__":
    array = Array(5)  # Initialize an array with capacity 5

    # Inserting elements into the array
    array.insert(0, 3)  # Expected output: True, the array becomes [3]
    array.insert(1, 5)  # Expected output: True, the array becomes [3, 5]
    array.insert(2, 6)  # Expected output: True, the array becomes [3, 5, 6]
    array.insert(3, 9)  # Expected output: True, the array becomes [3, 5, 6, 9]
    array.insert(4, 10)  # Expected output: True, the array becomes [3, 5, 6, 9, 10]

    # Try to insert an element when the array is already at capacity
    assert not array.insert(0, 100), "Expected insertion to fail because array is at capacity"

    print(array)  # Expected output: Array(capacity=5, data={0: 4, 1: 5, 2: 3, 3: 10, 4: 9})
    assert len(array) == 5, "Expected array length to be 5"
    assert array[1] == 5, "Expected element at index 1 to be 5"
    assert array[4] is not None, "Expected element at index 4 to exist"

    # Delete the first element
    del array[0]  # The array becomes {1: 5, 2: 3, 3: 10, 4: 9}
    print(array)  # Expected output: Array(capacity=5, data={1: 5, 2: 3, 3: 10, 4: 9})

    # Change the element at index 3
    array[3] = 7  # The array becomes {1: 5, 2: 3, 3: 7, 4: 9}
    print(array)  # Expected output: Array(capacity=5, data={1: 5, 2: 3, 3: 7, 4: 9})
